import { BenchmarkRunner } from "../../../utils/benchmarkTsSuite";
declare function print(arg:any) : string;

let MAXSIZE = 1000
function setObjectFunc(id:number,endid:number):any{
    if(id >= endid){
        return {
        Name : "Person_" + id.toString(),
        lastName : "Person_" + (id-1).toString(),
        person : null,
        id : id
        };
    }
    return {
        Name : "Person_" + id.toString(),
        lastName : "Person_" + (id-1).toString(),
        person : setObjectFunc(id + 1,endid),
        id : id
    };
}
function findObjectFunc(find_obj:any,size:number){
    var obj = {}
    for(var i=1;i<=size;i++){
        obj = find_obj["person"]
        find_obj = obj
    }
    return find_obj
}
function checkObjectFunc(obj:any,index:any){
    var find_obj = findObjectFunc(obj,index.id)
    if(JSON.stringify(find_obj)!=JSON.stringify(index)){
        print("find_obj: \n  "+JSON.stringify(find_obj))
        print("\n\nindex: \n  "+JSON.stringify(index))
        return false
    }
    return true
}
function checkObjectIdFunc(obj:any,id:number){
    var find_obj = findObjectFunc(obj,id)
    if(find_obj["id"]!=id){
        print("find_obj.id: "+find_obj.id+", id: "+id.toString()+" fail")
        return false
    }
    if(find_obj["Name"]!="Person_"+(id).toString()){
        print("find_obj.Name: "+find_obj.Name+",id: "+id.toString()+" fail")
        return false
    }
    if(find_obj["lastName"]!="Person_"+(id-1).toString()){
        print("find_obj.lastName: "+find_obj.lastName+",id: "+id.toString()+" fail")
        return false
    }
    return true
}
function runObjectAttributefunc(){
    for(var i=1;i<=MAXSIZE;i++){
        var obj = {
        Name : "Person",
        lastName : "Person",
        person : setObjectFunc(1,i),
        id : 0
        }
        var checkId = Math.floor(Math.random()*i)+1
        var check = checkObjectIdFunc(obj,checkId)
        if(i==77){
        var find_obj = findObjectFunc(obj,77)
        checkObjectFunc(obj,find_obj)
        }
        if (i==777){
        var objcheck = {
            Name : "Person_"+Math.floor(i/2).toString(),
            lastName : "Person_"+Math.floor(i/2-1).toString(),
            person : setObjectFunc(Math.floor(i/2+1),i),
            id : Math.floor(i/2)
        }
        checkObjectFunc(obj,objcheck)
        }
    }
}
class Person{
  Name:string
  lastName:string
  person:Person
  id:number
  constructor(name:string,lastName:string,person:Person, id:number){
    this.Name=name
    this.lastName=lastName
    this.person = person
    this.id=id
  }
}
function setPersonFunc(id:number,endid:number):Person{
  if(id == endid){
    return new Person(
      "Person_" + id.toString(),
      "Person_" + (id-1).toString(),
      null as any,
      id
    );
  }
  return new Person(
    "Person_" + id.toString(),
    "Person_" + (id-1).toString(),
    setPersonFunc(id + 1,endid),
    id
  );
}
function findPersonFunc(find_obj:Person,size:number):Person{
  var obj:Person
  for(var i=1;i<=size;i++){
    obj = find_obj.person
    find_obj = obj
  }
  return find_obj
}
function checkPersonFunc(obj:Person,index:Person){
  var find_obj = findPersonFunc(obj,index.id)
  if(JSON.stringify(find_obj)!=JSON.stringify(index)){
    print("find_obj: \n  "+JSON.stringify(find_obj))
    print("\n\nindex: \n  "+JSON.stringify(index))
    return false
  }
  return true
}
function checkPersonIdFunc(obj:Person,id:number):boolean{
  if(findPersonFunc(obj,id)["id"]!=id){
    print("id: "+id.toString()+" fail")
    return false
  }
  if(findPersonFunc(obj,id)["Name"]!="Person_"+(id).toString()){
    print("id: "+id.toString()+" fail")
    return false
  }
  if(findPersonFunc(obj,id)["lastName"]!="Person_"+(id-1).toString()){
    print("id: "+id.toString()+" fail")
    return false
  }
  return true
}
function runClassAttributefunc(){
  for(var i=1;i<=MAXSIZE;i++){
    var obj = new Person("Person","Person",setPersonFunc(1,i),0);
    var checkId = Math.floor(Math.random()*i)+1
    var check = checkPersonIdFunc(obj,checkId)
    if(i==77){
      var find_class = findPersonFunc(obj,77)
      checkPersonFunc(obj,find_class)
    }
  }
}
export function RunPropertyAccess1() {
  var start = new Date().getTime()
  runObjectAttributefunc()
  var end = new  Date().getTime()
  return (end - start);
}

let runner1 = new BenchmarkRunner("Property Access - RunPropertyAccess1", RunPropertyAccess1);
runner1.run();

export function RunPropertyAccess2() {
  var start = new Date().getTime()
  runClassAttributefunc()
  var end = new  Date().getTime()
  return (end - start);
}

let runner2 = new BenchmarkRunner("Property Access - RunPropertyAccess2", RunPropertyAccess2);
runner2.run();
